home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / Mail / cmd1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-08  |  7.7 KB  |  425 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)cmd1.c    5.18 (Berkeley) 1/16/89";
  20. #endif /* not lint */
  21.  
  22. #include "rcv.h"
  23.  
  24. /*
  25.  * Mail -- a mail program
  26.  *
  27.  * User commands.
  28.  */
  29.  
  30. /*
  31.  * Print the current active headings.
  32.  * Don't change dot if invoker didn't give an argument.
  33.  */
  34.  
  35. static int screen;
  36.  
  37. headers(msgvec)
  38.     int *msgvec;
  39. {
  40.     register int n, mesg, flag;
  41.     register struct message *mp;
  42.     int size;
  43.  
  44.     size = screensize();
  45.     n = msgvec[0];
  46.     if (n != 0)
  47.         screen = (n-1)/size;
  48.     if (screen < 0)
  49.         screen = 0;
  50.     mp = &message[screen * size];
  51.     if (mp >= &message[msgCount])
  52.         mp = &message[msgCount - size];
  53.     if (mp < &message[0])
  54.         mp = &message[0];
  55.     flag = 0;
  56.     mesg = mp - &message[0];
  57.     if (dot != &message[n-1])
  58.         dot = mp;
  59.     for (; mp < &message[msgCount]; mp++) {
  60.         mesg++;
  61.         if (mp->m_flag & MDELETED)
  62.             continue;
  63.         if (flag++ >= size)
  64.             break;
  65.         printhead(mesg);
  66.     }
  67.     if (flag == 0) {
  68.         printf("No more mail.\n");
  69.         return(1);
  70.     }
  71.     return(0);
  72. }
  73.  
  74. /*
  75.  * Scroll to the next/previous screen
  76.  */
  77. scroll(arg)
  78.     char arg[];
  79. {
  80.     register int s, size;
  81.     int cur[1];
  82.  
  83.     cur[0] = 0;
  84.     size = screensize();
  85.     s = screen;
  86.     switch (*arg) {
  87.     case 0:
  88.     case '+':
  89.         s++;
  90.         if (s * size > msgCount) {
  91.             printf("On last screenful of messages\n");
  92.             return(0);
  93.         }
  94.         screen = s;
  95.         break;
  96.  
  97.     case '-':
  98.         if (--s < 0) {
  99.             printf("On first screenful of messages\n");
  100.             return(0);
  101.         }
  102.         screen = s;
  103.         break;
  104.  
  105.     default:
  106.         printf("Unrecognized scrolling command \"%s\"\n", arg);
  107.         return(1);
  108.     }
  109.     return(headers(cur));
  110. }
  111.  
  112. /*
  113.  * Compute screen size.
  114.  */
  115. screensize()
  116. {
  117.     int s;
  118.     char *cp;
  119.  
  120.     if ((cp = value("screen")) != NOSTR && (s = atoi(cp)) > 0)
  121.         return s;
  122.     return screenheight - 4;
  123. }
  124.  
  125. /*
  126.  * Print out the headlines for each message
  127.  * in the passed message list.
  128.  */
  129.  
  130. from(msgvec)
  131.     int *msgvec;
  132. {
  133.     register int *ip;
  134.  
  135.     for (ip = msgvec; *ip != NULL; ip++)
  136.         printhead(*ip);
  137.     if (--ip >= msgvec)
  138.         dot = &message[*ip - 1];
  139.     return(0);
  140. }
  141.  
  142. /*
  143.  * Print out the header of a specific message.
  144.  * This is a slight improvement to the standard one.
  145.  */
  146.  
  147. printhead(mesg)
  148. {
  149.     struct message *mp;
  150.     char headline[LINESIZE], wcount[LINESIZE], *subjline, dispc, curind;
  151.     char pbuf[BUFSIZ];
  152.     struct headline hl;
  153.     int subjlen;
  154.  
  155.     mp = &message[mesg-1];
  156.     (void) readline(setinput(mp), headline, LINESIZE);
  157.     if ((subjline = hfield("subject", mp)) == NOSTR)
  158.         subjline = hfield("subj", mp);
  159.     /*
  160.      * Bletch!
  161.      */
  162.     curind = dot == mp ? '>' : ' ';
  163.     dispc = ' ';
  164.     if (mp->m_flag & MSAVED)
  165.         dispc = '*';
  166.     if (mp->m_flag & MPRESERVE)
  167.         dispc = 'P';
  168.     if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
  169.         dispc = 'N';
  170.     if ((mp->m_flag & (MREAD|MNEW)) == 0)
  171.         dispc = 'U';
  172.     if (mp->m_flag & MBOX)
  173.         dispc = 'M';
  174.     parse(headline, &hl, pbuf);
  175.     sprintf(wcount, "%3d/%-4ld", mp->m_lines, mp->m_size);
  176.     subjlen = screenwidth - 50 - strlen(wcount);
  177.     if (subjline == NOSTR || subjlen < 0)        /* pretty pathetic */
  178.         printf("%c%c%3d %-20.20s  %16.16s %s\n",
  179.             curind, dispc, mesg, nameof(mp, 0), hl.l_date, wcount);
  180.     else
  181.         printf("%c%c%3d %-20.20s  %16.16s %s \"%.*s\"\n",
  182.             curind, dispc, mesg, nameof(mp, 0), hl.l_date, wcount,
  183.             subjlen, subjline);
  184. }
  185.  
  186. /*
  187.  * Print out the value of dot.
  188.  */
  189.  
  190. pdot()
  191. {
  192.     printf("%d\n", dot - &message[0] + 1);
  193.     return(0);
  194. }
  195.  
  196. /*
  197.  * Print out all the possible commands.
  198.  */
  199.  
  200. pcmdlist()
  201. {
  202.     register struct cmd *cp;
  203.     register int cc;
  204.     extern struct cmd cmdtab[];
  205.  
  206.     printf("Commands are:\n");
  207.     for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
  208.         cc += strlen(cp->c_name) + 2;
  209.         if (cc > 72) {
  210.             printf("\n");
  211.             cc = strlen(cp->c_name) + 2;
  212.         }
  213.         if ((cp+1)->c_name != NOSTR)
  214.             printf("%s, ", cp->c_name);
  215.         else
  216.             printf("%s\n", cp->c_name);
  217.     }
  218.     return(0);
  219. }
  220.  
  221. /*
  222.  * Paginate messages, honor ignored fields.
  223.  */
  224. more(msgvec)
  225.     int *msgvec;
  226. {
  227.     return (type1(msgvec, 1, 1));
  228. }
  229.  
  230. /*
  231.  * Paginate messages, even printing ignored fields.
  232.  */
  233. More(msgvec)
  234.     int *msgvec;
  235. {
  236.  
  237.     return (type1(msgvec, 0, 1));
  238. }
  239.  
  240. /*
  241.  * Type out messages, honor ignored fields.
  242.  */
  243. type(msgvec)
  244.     int *msgvec;
  245. {
  246.  
  247.     return(type1(msgvec, 1, 0));
  248. }
  249.  
  250. /*
  251.  * Type out messages, even printing ignored fields.
  252.  */
  253. Type(msgvec)
  254.     int *msgvec;
  255. {
  256.  
  257.     return(type1(msgvec, 0, 0));
  258. }
  259.  
  260. /*
  261.  * Type out the messages requested.
  262.  */
  263. jmp_buf    pipestop;
  264.  
  265. type1(msgvec, doign, page)
  266.     int *msgvec;
  267. {
  268.     register *ip;
  269.     register struct message *mp;
  270.     register char *cp;
  271.     int nlines;
  272.     int brokpipe();
  273.     FILE *obuf;
  274.  
  275.     obuf = stdout;
  276.     if (setjmp(pipestop)) {
  277.         if (obuf != stdout) {
  278.             pipef = NULL;
  279.             Pclose(obuf);
  280.         }
  281.         signal(SIGPIPE, SIG_DFL);
  282.         return(0);
  283.     }
  284.     if (value("interactive") != NOSTR &&
  285.         (page || (cp = value("crt")) != NOSTR)) {
  286.         nlines = 0;
  287.         if (!page) {
  288.             for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++)
  289.                 nlines += message[*ip - 1].m_lines;
  290.         }
  291.         if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) {
  292.             cp = value("PAGER");
  293.             if (cp == NULL || *cp == '\0')
  294.                 cp = MORE;
  295.             obuf = Popen(cp, "w");
  296.             if (obuf == NULL) {
  297.                 perror(cp);
  298.                 obuf = stdout;
  299.             } else {
  300.                 pipef = obuf;
  301.                 signal(SIGPIPE, brokpipe);
  302.             }
  303.         }
  304.     }
  305.     for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
  306.         mp = &message[*ip - 1];
  307.         touch(mp);
  308.         dot = mp;
  309.         if (value("quiet") == NOSTR)
  310.             fprintf(obuf, "Message %d:\n", *ip);
  311.         (void) send(mp, obuf, doign ? ignore : 0, NOSTR);
  312.     }
  313.     if (obuf != stdout) {
  314.         pipef = NULL;
  315.         Pclose(obuf);
  316.     }
  317.     signal(SIGPIPE, SIG_DFL);
  318.     return(0);
  319. }
  320.  
  321. /*
  322.  * Respond to a broken pipe signal --
  323.  * probably caused by using quitting more.
  324.  */
  325.  
  326. brokpipe()
  327. {
  328.     longjmp(pipestop, 1);
  329. }
  330.  
  331. /*
  332.  * Print the top so many lines of each desired message.
  333.  * The number of lines is taken from the variable "toplines"
  334.  * and defaults to 5.
  335.  */
  336.  
  337. top(msgvec)
  338.     int *msgvec;
  339. {
  340.     register int *ip;
  341.     register struct message *mp;
  342.     int c, topl, lines, lineb;
  343.     char *valtop, linebuf[LINESIZE];
  344.     FILE *ibuf;
  345.  
  346.     topl = 5;
  347.     valtop = value("toplines");
  348.     if (valtop != NOSTR) {
  349.         topl = atoi(valtop);
  350.         if (topl < 0 || topl > 10000)
  351.             topl = 5;
  352.     }
  353.     lineb = 1;
  354.     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
  355.         mp = &message[*ip - 1];
  356.         touch(mp);
  357.         dot = mp;
  358.         if (value("quiet") == NOSTR)
  359.             printf("Message %d:\n", *ip);
  360.         ibuf = setinput(mp);
  361.         c = mp->m_lines;
  362.         if (!lineb)
  363.             printf("\n");
  364.         for (lines = 0; lines < c && lines <= topl; lines++) {
  365.             if (readline(ibuf, linebuf, LINESIZE) < 0)
  366.                 break;
  367.             puts(linebuf);
  368.             lineb = blankline(linebuf);
  369.         }
  370.     }
  371.     return(0);
  372. }
  373.  
  374. /*
  375.  * Touch all the given messages so that they will
  376.  * get mboxed.
  377.  */
  378. stouch(msgvec)
  379.     int msgvec[];
  380. {
  381.     register int *ip;
  382.  
  383.     for (ip = msgvec; *ip != 0; ip++) {
  384.         dot = &message[*ip-1];
  385.         dot->m_flag |= MTOUCH;
  386.         dot->m_flag &= ~MPRESERVE;
  387.     }
  388.     return(0);
  389. }
  390.  
  391. /*
  392.  * Make sure all passed messages get mboxed.
  393.  */
  394.  
  395. mboxit(msgvec)
  396.     int msgvec[];
  397. {
  398.     register int *ip;
  399.  
  400.     for (ip = msgvec; *ip != 0; ip++) {
  401.         dot = &message[*ip-1];
  402.         dot->m_flag |= MTOUCH|MBOX;
  403.         dot->m_flag &= ~MPRESERVE;
  404.     }
  405.     return(0);
  406. }
  407.  
  408. /*
  409.  * List the folders the user currently has.
  410.  */
  411. folders()
  412. {
  413.     char dirname[BUFSIZ];
  414.     char *cmd;
  415.  
  416.     if (getfold(dirname) < 0) {
  417.         printf("No value set for \"folder\"\n");
  418.         return 1;
  419.     }
  420.     if ((cmd = value("LISTER")) == NOSTR)
  421.         cmd = "ls";
  422.     (void) run_command(cmd, 0, -1, -1, dirname, NOSTR);
  423.     return 0;
  424. }
  425.